namespace Xmef.Engine
{
    using System;
    using System.Globalization;
    using Xmef.Interfaces;
    using Xmef.Library;
    using Xmef.Serializer;

    [Serializable]
    public class PropertyConverter : PluginIdentity, IPropertyConverter<string>, IPropertyConverter<bool>, IPropertyConverter<sbyte>, IPropertyConverter<byte>, IPropertyConverter<char>, IPropertyConverter<decimal>, IPropertyConverter<double>, IPropertyConverter<float>, IPropertyConverter<short>, IPropertyConverter<int>, IPropertyConverter<long>, IPropertyConverter<ushort>, IPropertyConverter<uint>, IPropertyConverter<ulong>, IPropertyConverter<TimeSpan>, IPropertyConverter<DateTime>, IPropertyConverter<DateTimeOffset>, IPluginIdentity
    {
        private static readonly IPluginIdentity _instance = new PropertyConverter();
        private static readonly IXmlStringSerializer<string> serializer = new XmlBase64StringSerializer<string>();

        public static T ConvertFromString<T>(string value)
        {
            return ConvertFromString<T>(_instance as IPropertyConverter<T>, value);
        }

        public static T ConvertFromString<T>(IPropertyConverter<T> converter, string value)
        {
            try
            {
                if (converter == null)
                {
                    converter = _instance as IPropertyConverter<T>;
                }
                if (converter != null)
                {
                    return converter.ConvertFromString(value);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorSync(ex);
            }
            return default(T);
        }

        public static string ConvertToString<T>(T value)
        {
            return ConvertToString<T>(_instance as IPropertyConverter<T>, value);
        }

        public static string ConvertToString<T>(IPropertyConverter<T> converter, T value)
        {
            try
            {
                if (converter == null)
                {
                    converter = _instance as IPropertyConverter<T>;
                }
                if (converter != null)
                {
                    return converter.ConvertToString(value);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorSync(ex);
            }
            return null;
        }

        bool IPropertyConverter<bool>.ConvertFromString(string s)
        {
            return bool.Parse(s);
        }

        string IPropertyConverter<bool>.ConvertToString(bool value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        byte IPropertyConverter<byte>.ConvertFromString(string s)
        {
            return byte.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<byte>.ConvertToString(byte value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        char IPropertyConverter<char>.ConvertFromString(string s)
        {
            return char.Parse(s);
        }

        string IPropertyConverter<char>.ConvertToString(char value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        DateTime IPropertyConverter<DateTime>.ConvertFromString(string s)
        {
            return DateTime.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<DateTime>.ConvertToString(DateTime value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        DateTimeOffset IPropertyConverter<DateTimeOffset>.ConvertFromString(string s)
        {
            return DateTimeOffset.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<DateTimeOffset>.ConvertToString(DateTimeOffset value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        decimal IPropertyConverter<decimal>.ConvertFromString(string s)
        {
            return decimal.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<decimal>.ConvertToString(decimal value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        double IPropertyConverter<double>.ConvertFromString(string s)
        {
            return double.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<double>.ConvertToString(double value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        short IPropertyConverter<short>.ConvertFromString(string s)
        {
            return short.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<short>.ConvertToString(short value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        int IPropertyConverter<int>.ConvertFromString(string s)
        {
            return int.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<int>.ConvertToString(int value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        long IPropertyConverter<long>.ConvertFromString(string s)
        {
            return long.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<long>.ConvertToString(long value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        sbyte IPropertyConverter<sbyte>.ConvertFromString(string s)
        {
            return sbyte.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<sbyte>.ConvertToString(sbyte value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        float IPropertyConverter<float>.ConvertFromString(string s)
        {
            return float.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<float>.ConvertToString(float value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<string>.ConvertFromString(string s)
        {
            return serializer.Deserialize(s);
        }

        string IPropertyConverter<string>.ConvertToString(string value)
        {
            return serializer.Serialize(value);
        }

        TimeSpan IPropertyConverter<TimeSpan>.ConvertFromString(string s)
        {
            return TimeSpan.Parse(s);
        }

        string IPropertyConverter<TimeSpan>.ConvertToString(TimeSpan value)
        {
            return value.ToString();
        }

        ushort IPropertyConverter<ushort>.ConvertFromString(string s)
        {
            return ushort.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<ushort>.ConvertToString(ushort value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        uint IPropertyConverter<uint>.ConvertFromString(string s)
        {
            return uint.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<uint>.ConvertToString(uint value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }

        ulong IPropertyConverter<ulong>.ConvertFromString(string s)
        {
            return ulong.Parse(s, CultureInfo.InvariantCulture);
        }

        string IPropertyConverter<ulong>.ConvertToString(ulong value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }
    }
}

